home *** CD-ROM | disk | FTP | other *** search
- /*
- * popups.c : Generic blocking popup routines
- *
- * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
- */
-
- #include <stdio.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Shell.h>
- #include <X11/Xaw/Dialog.h>
- extern Widget toplevel; /* this is the only external */
-
- /*
- * Functions defined here:
- */
- Widget createPopup(); /* Generic popup routines */
- void setPopupLabel();
- void popupMainLoop();
- void popupDone(); /* Call this when done */
-
- static void centerWidgetAndMouse();
-
- /*
- * Data defined here:
- */
- static int popupIsDone;
-
- /* - - - - - - - - */
-
- Widget
- createPopup(basename,num_buttons,callback)
- char *basename;
- int num_buttons;
- XtCallbackProc callback;
- {
- Widget shell,dialog;
- char name[256];
- int i;
-
- sprintf(name,"%sShell",basename);
- shell = XtCreatePopupShell(name,transientShellWidgetClass,toplevel,NULL,0);
- sprintf(name,"%sDialog",basename);
- dialog = XtCreateManagedWidget(name,dialogWidgetClass,shell,NULL,0);
- for (i=0; i < num_buttons; i++) {
- sprintf(name,"%sButton%d",basename,i);
- XawDialogAddButton(dialog,name,callback,(XtPointer)i);
- }
- XtRealizeWidget(shell);
- return(shell);
- }
-
- void
- setPopupLabel(w,basename,str)
- Widget w;
- char *basename,*str;
- {
- char name[256];
- Widget dialog;
- Arg args[1];
-
- sprintf(name,"%sDialog",basename);
- dialog = XtNameToWidget(w,name);
- XtSetArg(args[0],XtNlabel,str);
- XtSetValues(dialog,args,1);
- }
-
- /*
- * Popup "shell" with an exclusive grab, then dispatch events until
- * popupDone becomes True, then pop "shell" down.
- */
- void
- popupMainLoop(shell)
- Widget shell;
- {
- /* Go synchronous or the widgets don't resize properly */
- XSynchronize(XtDisplay(toplevel),True);
- /* Center the popup */
- centerWidgetAndMouse(shell,toplevel,shell);
- /* Beep */
- XBell(XtDisplay(toplevel),0);
- /* Pop it up and block until one of the buttons is clicked */
- popupIsDone = 0;
- XtPopup(shell,XtGrabExclusive);
- while (!popupIsDone) {
- /*
- * Only dispatch XEvents since we don't want input events or
- * timers to get in the way
- */
- XtAppProcessEvent(XtWidgetToApplicationContext(toplevel),XtIMXEvent);
- }
- /* Okay, pop it down */
- XtPopdown(shell);
- #ifndef DEBUG
- /* Back to normal */
- XSynchronize(XtDisplay(toplevel),False);
- #endif
- }
-
- void
- popupDone()
- {
- popupIsDone = 1;
- }
-
- /* - - - - - - - - */
- /*
- * Center widget "widget" inside widget "pwidget" and warp mouse to middle
- * of "mwidget".
- */
- static void
- centerWidgetAndMouse(widget,pwidget,mwidget)
- Widget widget,pwidget,mwidget;
- {
- Arg args[2];
- Window rwin,child;
- int x,y,px,py;
- unsigned int w,h,pw,ph,bw,d;
-
- /* Get child size */
- XGetGeometry(XtDisplay(widget),XtWindow(widget),
- &rwin,&x,&y,&w,&h,&bw,&d);
- /* Get parent size, position */
- XGetGeometry(XtDisplay(pwidget),XtWindow(pwidget),
- &rwin,&px,&py,&pw,&ph,&bw,&d);
- /* Need position in root window coords, don't ask me why */
- XTranslateCoordinates(XtDisplay(widget),XtWindow(pwidget),rwin,
- px,py,&x,&y,&child);
- px = x;
- py = y;
- /* Compute child position */
- x = px + pw/2 - w/2;
- if (x < 0)
- x = 0;
- else if (x > WidthOfScreen(XtScreen(widget))-w)
- x = WidthOfScreen(XtScreen(widget))-w;
- y = py + ph/2 - h/2;
- if (y < 0)
- y = 0;
- else if (y > HeightOfScreen(XtScreen(widget))-h)
- y = WidthOfScreen(XtScreen(widget))-h;
- /* Set child position */
- XtSetArg(args[0],XtNx,x);
- XtSetArg(args[1],XtNy,y);
- XtSetValues(widget,args,2);
- /* Get dest size, position */
- XGetGeometry(XtDisplay(mwidget),XtWindow(mwidget),
- &rwin,&x,&y,&w,&h,&bw,&d);
- /* Move mouse there */
- XWarpPointer(XtDisplay(mwidget),None,XtWindow(mwidget),
- 0,0,0,0,w/2,h/2);
- }
-